package net.tensor.tensorprovider.zhujie.anonation;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * @ClassName TokenAspect
 * @Description token校验自定义注解
 * @Author wangjian
 * @Date 19/06/25 13:29
 * @Version <1.0>
 */
@Aspect
@Component
@SuppressWarnings({"unused"})
public class TokenAspect {

    public static final Logger logger = LoggerFactory.getLogger(TokenAspect.class);

    public static final String TOKEN_KEY = "token";

    /**
     * checkUrl,keyUrl,tokenScope是通过Spring的@Value注解来获取配置文件中的配置项
     *
     * @Value等同于Spring原先的配置模式中的value <bean id="" class="">
     * <property name="" value="">
     * </bean>
     */
//    @Value(value = "${jwt.checkUrl}")
//    String checkUrl;
//
//    @Value(value = "${jwt.keyUrl}")
//    String keyUrl;
//
//    @Value(value = "${jwt.clientId}")
//    String tokenScope;

    @Pointcut("@annotation(net.tensor.tensorprovider.zhujie.anonation.Token)")
    public void annotationPointcut() {

    }

    @Before("annotationPointcut()")
    public void beforePointcut(JoinPoint joinPoint) {
        logger.info("参数校验之前"+joinPoint.toLongString());
    }

    @Around("annotationPointcut()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        String[] params = methodSignature.getParameterNames();// 获取参数名称
        Object[] args = joinPoint.getArgs();// 获取参数值
        if (null == params || params.length == 0) {
            String mes = "使用令牌注释时，令牌参数不会传递，并且该参数无效。";
            logger.info(mes);
            throw new Exception(mes);
        }
        boolean hasToken = false;
        int index = 0;
        for (int i = 0; i < params.length; i++) {
            if (TOKEN_KEY.equals(params[i])) {
                hasToken = true;
                index = i;
                break;
            }
        }
        if (!hasToken) {
            String mes = "令牌参数未包含在请求的参数中，该参数无效。";
            logger.info(mes);
            throw new Exception(mes);
        }
        this.checkToken(String.valueOf(args[index]));
        return joinPoint.proceed();
    }

    /**
     * 在切入点return内容之后切入内容（可以用来对处理返回值做一些加工处理）
     *
     * @param joinPoint
     */
    @AfterReturning("annotationPointcut()")
    public void doAfterReturning(JoinPoint joinPoint) {
        logger.info("参数校验之后"+joinPoint.toLongString());
    }

    private void checkToken(String token) {
        try {
            if (token.equals("1")) {
                logger.info("参数校验通过");
            }else {
                logger.error(String.format(" 参数值不合法,在%s,%d", new Throwable().getStackTrace()[0].getFileName(),new Throwable().getStackTrace()[0].getLineNumber()));
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
    }

}

